<?php

function __autoload ($className) {
	$classFile      = ENGINE_ROOT . '/classes/' . $className . '/' . $className . '.php';
	$classInterface = ENGINE_ROOT . '/classes/' . $className . '/i' . $className . '.php';
	
	if (!file_exists ($classFile) || !file_exists ($classInterface)) {
		trigger_error ('Class ' . $className . ' or his interface not found!', E_USER_ERROR);
	}
	
	$langFile = ENGINE_ROOT . '/classes/' . $className . '/i18n.php';
	
	if (file_exists ($langFile)) {
		loadLang ($langFile, $className);
	}
	
	include $classInterface;
	include $classFile;
}

/**
 * Свой mod_rewrite
 */
function rewriteURI () {
	include ENGINE_ROOT . '/URIs.php';
	
	if (empty ($REWRITE)) {
		throw new CoreException ('Rewrite rules not found!');
	}
	
	if (empty ($_REQUEST['u'])) {
		return;
	}
	
	$base = $_REQUEST['u'];
	
	foreach ($REWRITE as $find => $set) {
		$findLen = mb_strlen ($find);
		if ($find == mb_substr ($base, 0, $findLen) && (mb_strlen ($base) == $findLen || mb_substr ($base, $findLen, 1) == '/')) {
			$base = $set . mb_substr ($base, mb_strlen ($find));
			break;
		}
	}
	
	$_REQUEST['u'] = $base;
}

/**
 * Возвращает латинское название группы пользователя
 * @param integer $num номер группы
 * @return string
 */
function userGroup ($num) {
	$a = array (
		0 => 'admin',
		1 => 'moderator',
		2 => 'user',
		3 => 'guest'
	);
	
	$num = (int) $num;
	
	return isset ($a[$num]) ? $a[$num] : 'guest';
}

/**
 * Возвращает значение языковой переменной с ключем $label в подмассиве $key
 * @param string $label ключ переменной
 * @param string $key ключ подмассива (название модуля и т.п.)
 * @return string зачение; $label, если языковая переменная не определена
 */
function lang ($label, $key) {
	global $g_langCollection;
	return isset ($g_langCollection[$key][$label]) ? $g_langCollection[$key][$label] : $label;
}

/**
 * Подгружает массив с языковыми переменными из указанного файла в заданный подмассив
 * @param string $langFile полный путь до файла
 * @param string $key ключ подмассива (название модуля и т.п.)
 * @return void
 */
function loadLang ($langFile, $key) {
	global $g_langCollection;
		
	if (file_exists ($langFile)) {
		include $langFile;
		if (isset($LANG) && is_array ($LANG)) {
			if (isset($g_langCollection[$key])) {
				$g_langCollection[$key] = array_merge($g_langCollection[$key], $LANG);
			} else {
				$g_langCollection[$key] = $LANG;
			}
			unset ($LANG);
		}
	}
}

function getLangVars($key) {
	global $g_langCollection;
	
	return isset($g_langCollection[$key]) ? $g_langCollection[$key] : array();
}

/**
 * Возвращает защищенное значение переменной из массива $_REQUEST
 * @param string $key ключ переменной
 * @param string $type тип ожидаемого значения: s - строка, i - целое число, f - число с плавающей точкой, b - булевое выражение
 * @return mixed
 */
function getRequest ($key, $type = 's') {
	switch ($type) {
		case 's' :
		case 'str' :
		case 'string' : {
			return isset ($_REQUEST[$key]) ? $_REQUEST[$key] : '';
		}
		case 'i' :
		case 'int' :
		case 'integer' :
		case 'number' : {
			return isset ($_REQUEST[$key]) ? (int) $_REQUEST[$key] : 0;
		}
		case 'b' :
		case 'bool' :
		case 'boolean' : {
			return isset ($_REQUEST[$key]) ? true : false;
		}
		case 'f' :
		case 'float' : {
			return (float) isset ($_REQUEST[$key]) ? $_REQUEST[$key] : 0;
		}
		default : {
			return isset ($_REQUEST[$key]) ? $_REQUEST[$key] : '';
		}
	}
}

/**
 * Возвращает защищенное значение переменной из массива $_POST
 * @param string $key ключ переменной
 * @param string $type тип ожидаемого значения: s - строка, i - целое число, f - число с плавающей точкой, b - булевое выражение
 * @return mixed
 */
function getPost ($key, $type = 's') {
	switch ($type) {
		case 's' :
		case 'str' :
		case 'string' : {
			return isset ($_POST[$key]) ? $_POST[$key] : '';
		}
		case 'i' :
		case 'int' :
		case 'integer' :
		case 'number' : {
			return isset ($_POST[$key]) ? (int) $_POST[$key] : 0;
		}
		case 'b' :
		case 'bool' :
		case 'boolean' : {
			return isset ($_POST[$key]) ? true : false;
		}
		case 'f' :
		case 'float' : {
			return (float) isset ($_POST[$key]) ? $_POST[$key] : 0;
		}
		default : {
			return isset ($_POST[$key]) ? $_POST[$key] : '';
		}
	}
}

/**
 * Возвращает значение переменной из массива $_SERVER
 * @param string $key ключ переменной
 * @return mixed
 */
function getServer ($key) {
	return isset($_SERVER[$key]) ? $_SERVER[$key] : false;
}

/**
 * Возвращает защищенное значение cookie пользователя
 * @param string $key название переменной
 * @return string
 */
function getCookie ($key) {
	return isset($_COOKIE[$key]) ? safeSql ($_COOKIE[$key]) : '';
}

/**
 * Устанавливает значение cookie пользователя
 * @param string $name название переменной
 * @param mixed $value значение
 * @param integer $lifetime время жизни в секундах (по-умолчанию - берется значение из реестра "//settings/site/cookie_lifetime")
 * @return void
 */
function cmsSetCookie ($name, $value, $lifetime = false) {
	if ($lifetime === false) {
		$lifetime = Regedit::getInstance()->get ('//settings/site/cookie_lifetime');
	}
	
	setcookie ((string) $name, (string) $value, time() + $lifetime, '/');
}

/**
 * Возвращает значение переменной сессии пользователя
 * @param string $key имя переменной
 * @return string
 */
function getSession ($key) {
	return isset($_SESSION[$key]) ? safeSql ($_SESSION[$key]) : false;
}

/**
 * Устанавливает значение переменной сессии пользователя
 * @param string $name имя переменной
 * @param mixed $value значение
 * @return 
 */
function setSession ($name, $value) {
	$_SESSION[$name] = $value;
}

/**
 * Возвращает защищенную от mysql-иньекций строку
 * @param string $s
 * @return string
 */
function safeSql ($s, $force = false) {
	if ($force || !get_magic_quotes_gpc()) {
		if (is_string ($s)) {
			$s = mysql_real_escape_string ((string) $s);
			return $s;
		}
		elseif (is_array ($s)) {
			foreach ($s as $key => $v) {
				$s[$key] = mysql_real_escape_string ((string) $v);
			}
			return $s;
		} else {
			return $s; 
		}
	}
	
	return $s;
}

/**
 * Возвращает защищенную от строку, которую можно подставить в URI
 * @param string $s
 * @return string
 */
function safeURI ($s) {
	$s = str_replace (';', '', $s);
	$s = str_replace ("'", '', $s);
	$s = str_replace ('"', '', $s);
	$s = str_replace ('\\', '', $s);
	$s = mb_substr ($s, 0, 255);
	return $s;
}

/**
 * Перенаправляет пользователя на заданный URI
 * @param string $uri
 * @return void
 */
function redirect ($uri) {
	header ('Location: ' . $uri);
	exit;
}

/**
 * Перенаправляет пользователя на адрес переданный в переменной $_REQUEST['referer'] или $_SESSION['referer']
 * @param string $url URI, куда будет перенаправлен пользователь, если не будет значений двух вышеуказанных переменных
 * @return void
 */
function autoRedirect ($uri = '/') {
	if ($referer = getRequest('referer')) {
		header ('Location: ' . $referer);
	} elseif ($referer = getSession ('referer')) {
		header ('Location: ' . $referer);
	} else {
		header ('Location: ' . $uri);
	}
	exit;
}

/**
 * Шифрует строку с добавлением секретного ключа сайта
 * @param string $string
 * @return string
 */
function explayHash ($string) {
	return md5 (hash ('sha256', (string) $string));
}

/**
 * Преобразует символы строки в нижний регистр, заменяет русские буквы на созвучные латинские и экранирует/заменяет некоторые знаки препинания
 * @param string $string
 * @return string
 */
function translit ($string) {
	$aFrom = array ('й','ц','у','к','е','н','г','ш', 'щ', 'з','х','ъ','ф','ы','в','а','п','р','о','л','д','ж','э','я', 'ч', 'с','м','и','т','ь','б','ю', 'ё');
	$aTo   = array ('y','c','u','k','e','n','g','sh','sh','z','h','', 'f','i','v','a','p','r','o','l','d','j','e','ya','ch','s','m','i','t','', 'b','yu','e');
	$rel = array ();
	
	$cnt = count ($aFrom);
	
	for ($i = 0; $i < $cnt; ++$i) {
		$aFrom[$i] = '#' . $aFrom[$i] . '#iu';
	}
	
	$string = mb_strtolower ($string);
	$string = preg_replace ($aFrom, $aTo, $string);
	
	$string = preg_replace("/[\/\\\',\t`\^\[\]]*/", "", $string);
	$string = str_replace(chr(8470), "", $string);
	$string = preg_replace("/[ \.]+/", "_", $string);
	$string = preg_replace("/([_]+)/", "_", $string);
	//$string = trim(trim($string), "_");
	
	return $string;
}

/**
 * Функция преобразования времени в удобочитаемый формат
 * @param string $string время в формате UNIX
 * @return string
 */
function formatDate ($string, $isBirthdate = false) {
	$today = intval (date('H')) * 3600 + intval(date('i')) * 60 + intval(date('s'));

	if (date ('Y', $string) != date ('Y')) {
		$date = date ($isBirthdate ? 'd F Y' : 'd F Y, H:i', $string);
		$date = str_replace ("January", "Января", $date);
		$date = str_replace ("February", "Февраля", $date);
		$date = str_replace ("March", "Марта", $date);
		$date = str_replace ("April", "Апреля", $date);
		$date = str_replace ("May", "Мая", $date);
		$date = str_replace ("June", "Июня", $date);
		$date = str_replace ("July", "Июля", $date);
		$date = str_replace ("August", "Августа", $date);
		$date = str_replace ("September", "Сентября", $date);
		$date = str_replace ("October", "Октября", $date);
		$date = str_replace ("November", "Ноября", $date);
		$date = str_replace ("December", "Декабря", $date);
		return $date;
	}
	
	if ((time() - $string) < 120) {
		$date = 'только что';
	}
	elseif ((time() - $string) < 3600) {
		$date = getNumWithCase ((int) (date ('i', (time() - $string))), array ('минуту', 'минуты', 'минут'),false).' назад';
	}
	elseif ((time() - $string) < $today) {
		$date = 'сегодня в '.date('H:i', $string);
	}
	else {
		$date = date ($isBirthdate ? 'j F' : 'j F, H:i', $string);
		$date = str_replace ("January", "Января", $date);
		$date = str_replace ("February", "Февраля", $date);
		$date = str_replace ("March", "Марта", $date);
		$date = str_replace ("April", "Апреля", $date);
		$date = str_replace ("May", "Мая", $date);
		$date = str_replace ("June", "Июня", $date);
		$date = str_replace ("July", "Июля", $date);
		$date = str_replace ("August", "Августа", $date);
		$date = str_replace ("September", "Сентября", $date);
		$date = str_replace ("October", "Октября", $date);
		$date = str_replace ("November", "Ноября", $date);
		$date = str_replace ("December", "Декабря", $date);
	}
	return $date;
}

/**
 * Функция, возвращающая нужную форму слова в зависимости от значения числа $cnt (определение падежа)
 * @param integer $cnt число
 * @param $case массив из 3-х элементов - форм зависимого слова
 * @param boolean $word при установке этого параметра в true число равное нулю будет заменяться на слово "нет"
 * @return string
 */
function getNumWithCase ($cnt, $case, $word = true) {
        $cnt1 = $cnt;
        $cnt = str_replace ('-', '', $cnt);
        
        (mb_strlen($cnt) == 1) ? $minus = 1 : $minus = 2;
        $temp1 = mb_substr ($cnt, mb_strlen($cnt)-$minus, mb_strlen($cnt));
        $temp2 = mb_substr ($cnt, mb_strlen($cnt)-2, mb_strlen($cnt));
        if ($cnt == 0) $count = (($word) ? 'нет ' : '0 ').$case[2];
        elseif ($temp2 == 11 || $temp2 == 12 || $temp2 == 13 || $temp2 == 14) $count = "$cnt1 ".$case[2];
        elseif ($cnt == 1) $count = "$cnt1 ".$case[0];
        elseif ($temp1 == 2 || $temp1 == 3 || $temp1 == 4) $count = "$cnt1 ".$case[1];
        else $count = "$cnt1 ".$case[2];
        
        return $count;
}

/**
 * Функция подобная предыдущей, только не выводящяя само число $cnt
 */
function getCaseByNum ($cnt, $case, $word = true) {
        $cnt = str_replace ('-', '', $cnt);
        
        (mb_strlen($cnt) == 1) ? $minus = 1 : $minus = 2;
        $temp1 = mb_substr($cnt, mb_strlen($cnt)-$minus, mb_strlen($cnt));
        $temp2 = mb_substr($cnt, mb_strlen($cnt)-2, mb_strlen($cnt));
        if ($cnt == 0) $count = (($word) ? 'нет ' : '0 ').$case[2];
        elseif ($temp2 == 11 || $temp2 == 12 || $temp2 == 13 || $temp2 == 14) $count = $case[2];
        elseif ($cnt == 1) $count = $case[0];
        elseif ($temp1 == 2 || $temp1 == 3 || $temp1 == 4) $count = $case[1];
        else $count = $case[2];
        
        return $count;

}

function GET2String (array $get) {
	$a = array ();
	
	unset ($get['u'], $get['page'], $get['force_format']);
	
	foreach ($get as $key => $value) {
		if (is_array ($value)) {
			foreach ($value as $key2 => $value2) {
				$a[] .= $key . '[' . $key2 . ']=' . $value2;
			}
		} else {
			$a[] .= $key . ($value != '' ? '=' . $value : '');
		}
	}
	
	return implode ('&', $a);
}

function createHash ($numChars) {
	$s = '0123456789qwertyuiopasdfghjklzxcvbnm';
	
	$res = '';
	for ($i = 0; $i < $numChars; ++$i) {
		$res .= $s[mt_rand(0,mb_strlen($s)-1)];
	}
	
	return $res;
}